﻿using System;
using System.Collections.Generic;

namespace YArchitech.MEP
{
	public abstract class HYTube : HYComponent
	{
		public double Length { get; set; }

		public double Coefficient
		{
			get
			{
				return this.m_Coefficient;
			}
		}

		public double Re { get; set; }

		public double Rm { get; set; }

		public double Velocity
		{
			get
			{
				return this.m_Velocity;
			}
			set
			{
				this.m_Velocity = value;
			}
		}

		public double Roughness
		{
			get
			{
				return this.m_Roughness;
			}
			set
			{
				this.m_Roughness = value;
			}
		}

		public double DynamicPressure { get; set; }

		public double FrictionalResistance { get; set; }

		public double ShockResistance { get; set; }

		public double Resistance
		{
			get
			{
				return this.FrictionalResistance + this.ShockResistance;
			}
		}

		public string ShowString
		{
			get
			{
				return "管段" + base.Index.ToString();
			}
		}

		public bool IsLinkTerminal
		{
			get
			{
				return base.Next != null && base.Next is HYTerminal;
			}
		}

		public IEnumerable<HYTubeAttachment> Attachments
		{
			get
			{
				if (this.m_Attachments == null)
				{
					return null;
				}
				return this.m_Attachments.Values;
			}
		}

		public override void RebuildIndex(ref int index)
		{
			base.Index = index++;
			base.RebuildIndex(ref index);
		}

		public void ClearAttachments()
		{
			if (this.m_Attachments == null || this.m_Attachments.Count == 0)
			{
				return;
			}
			this.m_Attachments.Clear();
		}

		public void AddAttachment(HYComponent comp, string name, double val, int partIndex = 0)
		{
			if (this.m_Attachments == null)
			{
				this.m_Attachments = new Dictionary<int, HYTubeAttachment>();
			}
			if (this.m_Attachments.ContainsKey(comp.Id))
			{
				HYTubeAttachment hytubeAttachment = this.m_Attachments[comp.Id];
				hytubeAttachment.ShowName = name;
				hytubeAttachment.Value = val;
				hytubeAttachment.IsTerminal = (comp is HYTerminal);
				hytubeAttachment.PartIndex = partIndex;
				return;
			}
			HYTubeAttachment value = new HYTubeAttachment
			{
				Object = comp,
				ShowName = name,
				Value = val,
				PartIndex = partIndex,
				IsTerminal = (comp is HYTerminal)
			};
			this.m_Attachments.Add(comp.Id, value);
		}

		protected void CalAttachObjectInfo(out double coefficient, out double equipmentResistance)
		{
			coefficient = 0.0;
			equipmentResistance = 0.0;
			if (this.m_Attachments == null || this.m_Attachments.Count == 0)
			{
				return;
			}
			foreach (HYTubeAttachment hytubeAttachment in this.m_Attachments.Values)
			{
				if (hytubeAttachment.IsTerminal)
				{
					equipmentResistance += hytubeAttachment.Value;
				}
				else
				{
					coefficient += hytubeAttachment.Value;
				}
			}
		}

		public virtual void CalVelocity()
		{
			this.m_Velocity = Hydrokinetics.Velocity(base.Flow, base.Size.Area);
		}

		public virtual void CalRm(double roughness, double density, double viscosity)
		{
			double d = base.Size.D;
			double rs = base.Size.Rs;
			this.Re = Hydrokinetics.Re(d, this.m_Velocity, viscosity);
			double x = Hydrokinetics.x_TF_CW(this.Re, roughness);
			this.Rm = Hydrokinetics.Rm(x, rs, this.m_Velocity, density);
		}

		protected virtual void CalCoefficient()
		{
			double coefficient = 0.0;
			double terminalResistance = 0.0;
			this.CalAttachObjectInfo(out coefficient, out terminalResistance);
			this.TerminalResistance = terminalResistance;
			this.m_Coefficient = coefficient;
		}

		public override void Cal(HYSystemOption option)
		{
			base.Cal(option);
			this.CalVelocity();
			this.CalRm(this.m_Roughness, option.Density, option.Viscosity);
			this.DynamicPressure = Hydrokinetics.DynamicPressure(this.m_Velocity, option.Density);
			this.Rm *= option.RoughnessFix;
			this.Rm *= option.FrictionFix;
			this.FrictionalResistance = this.Rm * this.Length;
			this.TerminalResistance = 0.0;
			this.CalCoefficient();
			this.ShockResistance = this.m_Coefficient * this.DynamicPressure;
			this.ShockResistance *= option.ShockFix;
			this.ShockResistance += this.TerminalResistance;
		}

		protected double m_Coefficient;

		protected double m_Velocity;

		protected double m_Roughness;

		private Dictionary<int, HYTubeAttachment> m_Attachments;

		protected double TerminalResistance;
	}
}
